package cn.virens.common.apifox.apifox;

import cn.virens.common.apifox.apifox.build.ApiFoxCollection;
import cn.virens.common.util.exception.APIException;
import com.alibaba.fastjson2.JSON;
import org.apache.commons.text.StringEscapeUtils;
import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.io.resource.ResourceUtil;
import org.dromara.hutool.core.text.StrUtil;

import java.io.InputStream;
import java.util.List;

public class ApifoxScan {
    public final static String APIFOX_DEF_HEADER = "classpath:META-INF/apifox_def_header.tpl";
    public final static String APIFOX_DEF_QUERY = "classpath:META-INF/apifox_def_query.tpl";

    public final static String APIFOX_PROC_POST = "classpath:META-INF/apifox_proc_post.tpl";
    public final static String APIFOX_PROC_PRE = "classpath:META-INF/apifox_proc_pre.tpl";
    public final static String APIFOX = "classpath:META-INF/apifox.tpl";

    /**
     * 读取配置文件
     */
    public static String readFile(String url) throws APIException {
        try (InputStream in = ResourceUtil.getStream(url)) {
            return IoUtil.readUtf8(in);
        } catch (Exception e) {
            throw APIException.warp(e);
        }
    }

    /**
     * 扫描指定包路径，返回APIFOX文档
     */
    public static String scanPackageToDocs(String pkg) throws APIException {
        return scanPackageTpl(pkg, readFile(APIFOX));
    }

    /**
     * 扫描指定包路径，返回接口列表
     */
    public static List<ApiFoxCollection> scanPackage(String pkg) throws APIException {
        return scanPackage(pkg, new ApifoxTree());
    }

    /**
     * 扫描指定包路径，返回接口列表
     */
    public static List<ApiFoxCollection> scanPackage(String pkg, ApifoxTree tree) throws APIException {
        ApifoxScanner apifoxScanner = new ApifoxScanner();

        apifoxScanner.setApifoxHeader(readFile(APIFOX_DEF_HEADER));
        apifoxScanner.setApifoxQuery(readFile(APIFOX_DEF_QUERY));

        return apifoxScanner.scanPackage(pkg, tree);
    }

    /**
     * 扫描包路径：并根据默认的模板生成对应的接口文档
     */
    private static String scanPackageTpl(String packageName, String baseFile) throws APIException {
        String procPostFile = StringEscapeUtils.escapeJava(readFile(APIFOX_PROC_POST));
        String procPreFile = StringEscapeUtils.escapeJava(readFile(APIFOX_PROC_PRE));

        baseFile = StrUtil.replace(baseFile, "_API_DOCS_", scanPackageStr(packageName));
        baseFile = StrUtil.replace(baseFile, "_APIFOX_PROC_POST_", procPostFile);
        baseFile = StrUtil.replace(baseFile, "_APIFOX_PROC_PRE_", procPreFile);

        return baseFile;
    }

    private static String scanPackageStr(String pkg) throws APIException {
        return JSON.toJSONString(scanPackage(pkg));
    }

}
